// 向客户端输入一个字符串，并得到输出
#include <string>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

const size_t inform_size = 1024;

void usage(const char *cmd)
{
    printf("usager:%s dst_ip dst_port\n", cmd);
}

int main(int argc, char *args[])
{
    if (argc != 3)
    {
        usage(args[0]);
        return 0;
    }
    char inbuffer[inform_size] = {0};
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    // 对于客户端来说，为了防止端口号相互占用问题，一般不允许自己绑定端口号，交给系统来随机绑定
    // 所以对于客户端来说，不需要进行bind操作
    struct sockaddr_in dest;
    memset(&dest, 0, sizeof dest);
    dest.sin_family = AF_INET;
    dest.sin_addr.s_addr = inet_addr(args[1]);
    dest.sin_port = htons(atoi(args[2]));
    while (true)
    {
        std::cout << "please enter message: ";
        std::string message;
        getline(std::cin, message);
        // 1. 发送请求
        // std::cout << message << std::endl;
        ssize_t n = sendto(sockfd, message.c_str(), message.size(), 0, (const sockaddr *)&dest, sizeof dest);
        // std::cout << "send!\n";
        if (n < 0)
        {
            std::cout << "send message error\n";
            continue;
        }
        // 2. 接收响应
        // udp协议允许所有人发送，所以需要甄别是否是所需的相应
        sockaddr_in tmp;
        socklen_t len = sizeof tmp;
        n = recvfrom(sockfd, inbuffer, sizeof inbuffer - 1, 0, (sockaddr *)&tmp, &len);
        if (n > 0)
        {
            inbuffer[n] = '\0';
            std::cout << inbuffer << std::endl;
        }
    }
    return 0;
}